package com.zx.ishopping.utils;


import com.zx.ishopping.Constants.RegisterConstant;
import com.zx.ishopping.exceptions.RegisterFailException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;

import java.util.Random;
import java.util.concurrent.TimeUnit;

@Component
public class VerificationCodeUtil {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private JavaMailSender mailSender;

    @Value("${spring.mail.username}")
    private String fromEmail;

    @Value("${app.captcha.expire-minutes}")
    private int expireMinutes;


    /**
     * 生成验证码长度为6的随机验证码
     * 
     * @return 生成的验证码
     */
    public String generateVerificationCode() {
        // 验证码字符集，排除容易混淆的字符
        String chars = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ";
        Random random = new Random();
        StringBuilder code = new StringBuilder();

        for (int i = 0; i < 6; i++) {
            int index = random.nextInt(chars.length());
            code.append(chars.charAt(index));
        }

        return code.toString();
    }


    /**
     * 发送验证码到指定邮箱
     * @param toEmail 目标邮箱
     * @param code 验证码
     * @return 是否发送成功
     */
    public boolean sendVerificationCode(String toEmail, String code) {
        try {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom(fromEmail);
            message.setTo(toEmail);
            message.setSubject("【iShopping】您的验证码");
            message.setText(String.format("您的验证码是：%s，有效期为%d分钟。请不要向他人泄露您的验证码。",
                    code, expireMinutes));

            mailSender.send(message);
            return true;
        } catch (Exception e) {
            // 可以根据实际情况记录日志
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 将验证码存储到Redis，并设置过期时间
     * @param key 存储的键（建议使用邮箱作为键）
     * @param code 验证码
     */
    public void storeVerificationCode(String key, String code) {
        redisTemplate.opsForValue().set(key, code, expireMinutes, TimeUnit.MINUTES);
    }


    /**
     * 验证验证码是否正确
     * @param key 存储的键（建议使用邮箱作为键）
     * @param inputCode 用户输入的验证码
     * @return 验证结果
     */
    public boolean verifyCode(String key, String inputCode) {
        if (inputCode == null || inputCode.isEmpty()) {
            throw new RegisterFailException(RegisterConstant.CODE_IS_NULL) ;
        }

        String storedCode = redisTemplate.opsForValue().get(key);
        if (storedCode == null) {
            // 验证码不存在或已过期
            throw new RegisterFailException(RegisterConstant.CODE_EXPIRE);
        }
        
        if (!storedCode.equalsIgnoreCase(inputCode)) {
            throw new RegisterFailException(RegisterConstant.CODE_ERROR);
        }

        redisTemplate.delete(key);
        // 忽略大小写比较验证码
        return true;
    }

}
